﻿using Common.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Common.EF
{
    public interface ICommonContext
    {
        Task<T> GetEntityAsync<T>(Expression<Func<T, bool>> predicate, string[] includes)
             where T : EntityBase, new();

        Task<List<T>> GetEntitiesAsync<T>(Expression<Func<T, bool>> predicate, string[] includes)
              where T : EntityBase, new();

        Task<List<T>> GetOrderEntitiesAsync<T>(Expression<Func<T, bool>> predicate, Dictionary<string, int> orders, string[] includes)
              where T : EntityBase, new();

        Task<ApiPagedResult<T>> GetOrderPageEntitiesAsync<T>(Expression<Func<T, bool>> predicate, Dictionary<string, int> orders, int startIndex, int pageSize, string[] includes)
              where T : EntityBase, new();

        Task<int> GetCountAsync<T>(Expression<Func<T, bool>> predicate)
             where T : EntityBase, new();

        Task<decimal> GetSumAsync<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, decimal>> sumExpression)
             where T : EntityBase, new();

        Task<List<IGrouping<S, T>>> GetGroupByAsync<T, S>(Expression<Func<T, bool>> predicate, Expression<Func<T, S>> groupBy)
             where T : EntityBase, new();

        T GetEntity<T>(Expression<Func<T, bool>> predicate, string[] includes)
           where T : EntityBase, new();

        List<T> GetEntities<T>(Expression<Func<T, bool>> predicate, string[] includes)
            where T : EntityBase, new();

        List<T> GetOrderEntities<T>(Expression<Func<T, bool>> predicate, Dictionary<string, int> orders, string[] includes)
            where T : EntityBase, new();

        ApiPagedResult<T> GetOrderPageEntities<T>(Expression<Func<T, bool>> predicate, Dictionary<string, int> orders, int startIndex, int pageSize, string[] includes)
            where T : EntityBase, new();

        int GetCount<T>(Expression<Func<T, bool>> predicate)
           where T : EntityBase, new();

        decimal GetSum<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, decimal>> sumExpression)
           where T : EntityBase, new();

        List<IGrouping<S, T>> GetGroupBy<T, S>(Expression<Func<T, bool>> predicate, Expression<Func<T, S>> groupBy)
           where T : EntityBase, new();

        void AddEntities<T>(List<T> entities)
          where T : EntityBase, new();

        void UpdateEntities<T>(List<T> entities, List<T> entitiesDb, params string[] updateProperies)
          where T : EntityBase, new();

        void UpdateEntitiesByByCommit<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> updateExpression)
           where T : EntityBase, new();

        void DeleteEntity<T>(Expression<Func<T, bool>> predicate)
           where T : EntityBase, new();

        void DeleteEntityByCommit<T>(Expression<Func<T, bool>> predicate)
           where T : EntityBase, new();

        Task AddEntitiesAsync<T>(List<T> entities)
       where T : EntityBase, new();

        Task UpdateEntitiesAsync<T>(List<T> entities, List<T> entitiesDb, params string[] updateProperies)
          where T : EntityBase, new();

        Task DeleteEntityAsync<T>(Expression<Func<T, bool>> predicate)
           where T : EntityBase, new();

        Task DeleteEntityByCommitAsync<T>(Expression<Func<T, bool>> predicate)
           where T : EntityBase, new();

        Task UpdateEntitiesByByCommitAsync<T>(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> updateExpression)
           where T : EntityBase, new();

        void Dispose();

        int SaveChanges();

        Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
    }
}
